class Player {
  constructor(socket, name) {
    this.socket = socket; //socket对象
    this.name = name;  //玩家昵称
    this.roomId = null; //当前所在房间
    this.state = 0;  // 0代表空闲, 1在游戏中
    this.pipei = false  // 是否在匹配,默认不匹配
    this.firstFlag = false; //是否是第一个出牌的玩家
    this.flag = false  // 是否轮到这个玩家出牌
    this.cardsNumber = 0;  //玩家手中的牌
    this.timer = null;  //定时器
    this.order = 0; //出牌顺序
    this.check = false; //是否过牌
    this.pokers = []; //玩家手里牌
    this.prePlayCards = null; //上一次出过的牌
    const _this = this; //玩家自身

    global.playerCount++; //添加在线玩家
    this.init(_this);
  }
  init(_this) {
    this.exit(_this);
  }
  // 清除定时器
  clearTimter() {
    clearInterval(this.timer)
    this.timer = null;
  }
  // 玩家退出游戏
  exit(_this) {
    _this.socket.on('disconnect', function () {
      clearInterval(_this.timer);  //关闭定时器
      global.players = global.players.filter(item => {
        return item.name !== _this.name;
      })
      global.playerCount--;  //减少在线玩家
    })
  }
  // 加入房间
  joinRoom(roomId){
    this.socket.join(roomId);
    this.roomId = roomId;
  }
  // 开始游戏
  play() {
    this.socket.emit('play', { code: 0, message: "匹配成功~即将进入游戏界面...." })
  }
  // 发牌
  licensing(pokers, player) {
    const _this = this;
    // return new Promise((resolve, reject) => {
    pokers.forEach(poker => {
      _this.pokers.push(poker); //将管理员发的牌存到自身带的牌中
    })
    player.socket.emit('licensing', { code: 0, message: `玩家：${player.name}`, pokers: _this.pokers });
    // resolve(pokers);
    // })
  }
  // 出牌
  playCards(before, check) {
    const _this = this;
    // 初始化返回值,默认为不出牌状态
    return new Promise((resolve, reject) => {

      // 第一个出牌的玩家
      if (this.firstFlag || check) {
        _this.socket.on('playCards', data => {
          // 判断传过来的牌不为空才处理
          if (data && data.pokers != null || data.pokers != undefined) {
            // 做出牌处理
            _this.flag = false; //将出牌状态设置为false
            _this.prePlayCards = data.pokers; //设置当前要出的牌
            _this.socket.to(_this.roomId).emit('playCards', { code: 0, message: "出牌成功！", pokers: _this.prePlayCards })
            // 返回出过的牌
            resolve(_this.prePlayCards);
          } else {
            socket.emit("playCards", { code: 0, message: `请选择牌在进行操作` })
          }
        })
      }

      // 轮到该玩家出牌
      if (this.flag) {
        _this.socket.on('playCards', data => {
          // 判断是否出牌
          if (data && data.check) {
            // ---不出牌直接返回状态
            _this.check = true; //过牌'
            _this.flag = false; //将出牌状态设置为false
            _this.prePlayCards = null; //设置当前要出的牌
            resolve(_this.prePlayCards);
          } else {
            // ---出牌做比对
            // 判断传过来的牌不为空才处理
            if (data && data.pokers != null || data.pokers != undefined) {
              // 做出牌处理
              this.compareCards(before, data.pokers, _this.socket);
              _this.check = false; //返回出牌状态
              _this.flag = false; //将出牌状态设置为false
              _this.prePlayCards = data.pokers; //设置当前要出的牌
              // 返回出过的牌
              resolve(_this.prePlayCards);
            } else {
              socket.emit("playCards", { code: 0, message: `请选择牌在进行操作` })
            }
          }

        })
      } else {
        socket.emit("playCards", { code: 0, message: `还没轮到你出牌` })
      }
    })

  }
  // 匹配成功,初始化玩家状态
  initPlayState() {
    this.state = 1; //游戏中
    this.pipei = false; //结束匹配
  }
  // 比牌
  compareCards(before, after, socket) {
    socket = socket || this.socket;
    // 判断传过来的牌是否与上家出牌的类型相等，再做处理
    if (before.constructor === after.constructor) {
      // 先处理传过来的牌，如果是单张直接比，多张牌需要遍历再做处理
      // 传过来的牌为对象，是单张
      if (after.constructor === Object) {
        // 先比牌
        if (after.size > before.size) {
          // 可以放
          socket.to(tihs.roomId).emit("playCards", { code: 0, message: `出牌成功`, after })
        } else {
          // 不可以放
          socket.emit("playCards", { code: 0, message: `出牌失败,牌面小于上家`, after })
        }
        // 传过来的牌为数组，是多张
      } else if (after.constructor === Array) {
        // 判断出牌张数是否与上家相同
        if (after.length != before.length) {
          socket.emit("playCards", { code: 0, message: `出牌失败,出牌张数与上家张数不符合`, after })
        } else {
          // 判断多张牌的牌面是否相同
          let flag = after.some((item, index, arr) => {
            return item.points === arr[0].points;
          });
          // 牌面相同
          if (flag) {
            // 对比前后出牌的第一张牌，如果大于上一家的牌面，可以出牌
            if (after[0].size > before[0].size) {
              // 可以放
              socket.to(this.roomId).emit("playCards", { code: 0, message: `出牌成功`, after })
            } else {
              // 不可以放
              socket.emit("playCards", { code: 0, message: `出牌失败,牌面小于上家`, after })
            }
            // 牌面不相同
          } else {
            socket.emit("playCards", { code: 0, message: `出牌失败,牌面类型不符合出牌规则`, after })
          }
        }
      }
    } else {
      socket.emit("playCards", { code: 0, message: `出牌失败,牌面与上家不符合类型`, after })
    }
  }
  // 等待对局结束
  awaitGameEnd() {
    this.socket.emit("awaitGameEnd", { code: 0, message: "等待对局结束", flag: true });
  }
  // 监听自身牌数和其他玩家牌数
  cardsCount(cardsCount) {
    const _this = this;

    return new Promise((resolve, reject) => {
      this.socket.emit("cardsCount", { code: 0, message: "玩家牌数", cardsCount })
      resolve();
    })
  }
  // 监听系统出牌
  sysPlayCards(cards){
    this.socket.emit("sysPlayCards", { code: 0, message: "系统出牌", cards })
  }
  // 监听谁出牌
  chupai() {
    this.socket.emit("chupai", { code: 0, message: "轮到你出牌了", data: null })
  }

}

module.exports = Player;